# API Permissions (Registered Application)

Reference for the Azure AD (Entra ID) app registration permissions required by the provisioning service when using app-only authentication. Required permissions depend on which features are enabled — grant only the permissions needed for the features in use.

All permissions below are Application permissions (not Delegated) and require admin consent. Microsoft Graph permissions link to the Microsoft Graph permissions reference (opens new window); SharePoint (certificate authentication) permissions are documented at Granting access using SharePoint App-Only (opens new window).

# How to read this reference

Although the service authenticates once, that single app registration is used to request two independent resource tokens: a SharePoint token for CSOM calls (ClientContext), and a Microsoft Graph token for Graph SDK/REST calls (GraphServiceClient / MSGraph.GetAppToken()). Granting a permission on a resource the code never actually calls does nothing — the tables below list, per feature, exactly which resource(s) its code calls, verified against the current implementation.

# Document libraries

Used by: every ClientMatterDesignMatterSiteCollection, MatterSite, MatterDocLib, ClientSiteCollection_MatterSite, ClientSiteCollection_MatterDocLib, ClientSite_MatterSite, ClientSite_MatterDocLib, and MatterOffice365Group. All of them ultimately create/update a document library (DocLibCfg) inside whatever site the design provisions, so the permission requirement below is the universal baseline — but on MatterOffice365Group it must be granted as Sites.FullControl.All, not Sites.Selected; see Office 365 Groups.

Document library provisioning (DocLibCfg, without Planner, a group-backed design, or a DefaultSensitivityLabelName) is implemented entirely through SharePoint CSOM — the document library creation/update path never requests a Microsoft Graph token in that case. (SPDocumentLibrary does call Graph elsewhere — GetDriveId and GetIDInformation for the per-file sensitivity label handler and the Cicero integration respectively, and SensitivityLabelRepository.FindAndProcess when DefaultSensitivityLabelName is configured (see Library default sensitivity label) — but none of that is required for provisioning itself.) Only the SharePoint permission is required for this feature in isolation.

API Permission Why needed Broader alternative
SharePoint (certificate authentication) Sites.Selected Grants access only to the specific site collections explicitly authorized for the app, so document library operations (create/update libraries, folders, item permissions) work without a tenant-wide site grant. Sites.FullControl.All (tenant-wide, trades the per-site scoping of Sites.Selected for tenant-wide access).

No Microsoft Graph permission is required for this feature alone — the code never calls Microsoft Graph here. A Graph permission becomes necessary only if one of these other DocLibCfg-attached features is also used on the same library, and each needs its own, different Graph permission (not Sites.Selected):

  • PlannerSet — needs Tasks.ReadWrite.All/Group.Read.All; see Planner.
  • The Update Doclib File Sensitivity Label file handler — needs Sites.Read.All/Sites.ReadWrite.All, Files.Read.All/Files.ReadWrite.All, and InformationProtectionPolicy.Read.All; see Per-file sensitivity label.

DefaultSensitivityLabelName (the library's own default sensitivity label) needs only InformationProtectionPolicy.Read.All — see Library default sensitivity label.

# Site collections (standard CSOM creation)

Used by: MatterSiteCollection, ClientSiteCollection_MatterSite, ClientSiteCollection_MatterDocLib — the only designs that create a new site collection (via SPSiteCollection/SiteCollectionCfg). The other non-group designs (MatterSite, ClientSite_MatterSite, ClientSite_MatterDocLib) only create a subsite (Web.Webs.Add) within a site the app already has access to, so they need no permission beyond Document libraries; MatterDocLib creates no new site or subsite at all.

Site creation (Tenant.CreateSite) and term-store reads/writes (SPTermStore, using the CSOM Taxonomy API) are both SharePoint CSOM calls — no Microsoft Graph token is requested for either.

API Permission Why needed Broader alternative
SharePoint (certificate authentication) Sites.FullControl.All A site collection that doesn't exist yet can't be authorized individually via Sites.Selected; creating and fully managing it requires tenant-wide site control. None — already the broadest SharePoint app-only permission level.
SharePoint (certificate authentication) TermStore.ReadWrite.All Provisioning reads and writes managed metadata (term store) as part of site setup. None broader. Narrower option: see note below.

Conditional: if Classification is configured on the SiteCollectionCfg (see Site Collection Configuration), updating it calls Microsoft Graph even for a CSOM-created site — SPSiteCollection.UpdateSiteCollection passes a Graph app token into the classification update whenever the configured value differs from the site's current one. This additionally requires:

API Permission Why needed Broader alternative
Microsoft Graph Group.ReadWrite.All (opens new window) Site classification is written through Graph even when the site collection itself was created via CSOM. Directory.ReadWrite.All — not recommended unless already required for another reason.

# Site collections via Graph (UseGraphSiteCreation)

Used by: the same three designs as standard CSOM creation above — MatterSiteCollection, ClientSiteCollection_MatterSite, ClientSiteCollection_MatterDocLib — when their SiteCollectionCfg also has UseGraphSiteCreation enabled.

Used when UseGraphSiteCreation is enabled on a SiteCollectionCfg, to reduce the permission footprint versus the standard CSOM path above — no tenant-wide Sites.FullControl.All is required.

Only site creation goes through Graph. The follow-up configuration that runs afterward regardless of creation method — SPSiteCollection.UpdateSiteCollection (permission sets, page-extension validation, tenant settings) and SPTermStore (term store) — is SharePoint CSOM, not Graph.

API Permission Why needed Broader alternative
Microsoft Graph Sites.Create.All (opens new window) Creates the site collection via Graph, avoiding the tenant-wide Sites.FullControl.All grant. Sites.FullControl.All — but that removes the point of UseGraphSiteCreation; grant it via the standard CSOM creation set above instead.
Microsoft Graph Sites.Selected (opens new window) Needed for further Graph-side access to the site after creation. When a site is created via Graph, the app is automatically granted access to that site under Sites.Selected, so no manual per-site grant is needed for sites created this way. Sites.ReadWrite.All or Sites.FullControl.All (tenant-wide, same trade-off as in Document libraries).
SharePoint (certificate authentication) Sites.Selected Covers the CSOM follow-up configuration (UpdateSiteCollection, permission sets) that runs against the newly created site. Auto-granted alongside the Graph grant above, the same way the Graph row above describes — no separate manual per-site grant needed, but the permission itself must still be present on the app registration. Sites.FullControl.All (tenant-wide).
SharePoint (certificate authentication) TermStore.ReadWrite.All Term-store reads/writes (SPTermStore) are CSOM Taxonomy calls, not Graph — required regardless of UseGraphSiteCreation. None broader. Narrower option: see note below.

Sites.Create.All alone is not sufficient: it only allows creating the site collection; Sites.Selected is required for the follow-up changes above.

For SharePoint REST/CSOM operations or site-level permission grants on a specific site (rather than through Graph), the SharePoint-side resource-specific permission (RSP) equivalent is site.selected.

This reduced permission set only covers site collections created by a SiteCollectionCfg. It does not cover Office 365 Group based designs (such as ClientMatterDesign = MatterOffice365Group): the site provisioned for a group is not created through Graph site creation, so the app never receives a Sites.Selected grant on it, and reading the group's drive to locate the site requires a Graph read permission (Group.ReadWrite.All, Sites.Read.All, or Files.Read.All) that Sites.Create.All does not include. Group based designs require the Office 365 Groups permission set. A missing read permission shows up in the log as repeated No drive linked to the office365 group warnings.

The Classification conditional dependency described above applies here too — UpdateSiteCollection is shared code, run regardless of which method created the site.

# Office 365 Groups

Used by: MatterOffice365Group only — the sole ClientMatterDesign value backed by a Microsoft 365 group.

SPOffice365Group calls Microsoft Graph only for the group itself (graphClient.Groups, graphClient.Users) — it never calls the Graph Sites API or the Graph term store API. Once the group's site URL is resolved, all site-level configuration (CSOM operations, permission grants, term store) runs through SharePoint CSOM instead.

API Permission Why needed Broader alternative
Microsoft Graph Group.ReadWrite.All (opens new window) Creates, updates, and deletes the Microsoft 365 group backing the site, including membership, ownership, and classification changes. Directory.ReadWrite.All — full directory write (users, groups, devices, etc.), not group-specific. Not recommended unless already required for another reason.
Microsoft Graph User.Read.All (opens new window) Resolves users to add as group owners and members. Directory.Read.All — reads users plus all other directory objects. Not recommended unless already required for another reason.
SharePoint (certificate authentication) Sites.FullControl.All The group's site is not created through Graph site creation, so it never receives an automatic Sites.Selected grant — full site management (CSOM operations, permission grants) needs this instead. None — already the broadest Sites permission.
SharePoint (certificate authentication) TermStore.ReadWrite.All Term-store reads/writes (SPTermStore) are CSOM Taxonomy calls, not Graph. None broader. Narrower option: see note below.

# Reduced Microsoft Graph set for Office 365 Groups (limitations apply)

Instead of Group.ReadWrite.All, the Office 365 Groups design can run with a reduced Microsoft Graph permission set (verified July 2026):

API Permission Why needed Broader alternative
Microsoft Graph Group.Create (opens new window) Lets the app manage (update properties, add/remove members, add owners, delete) only the groups it created itself, instead of every group in the tenant. Group.ReadWrite.All — drops the "created by this app" restriction and the limitations listed below; this is the full set above.
Microsoft Graph Group.Read.All (opens new window) Covers group lookup and locating the group's site. Group.ReadWrite.All (see above; redundant if already granted).
Microsoft Graph User.Read.All (opens new window) Resolves users to add as group owners and members. Directory.Read.All — not recommended unless already required elsewhere.
SharePoint (certificate authentication) Sites.FullControl.All, TermStore.ReadWrite.All Unchanged from the full set above. None.

With Group.Create, the app can manage the groups it created itself (update properties, add/remove members, add owners, delete), and Group.Read.All covers the group lookup and locating the group's site. Limitations of the reduced set:

  • Owners cannot be removed. When the configured owners shrink, the removal is skipped and a warning is logged (removing owners requires the Group.ReadWrite.All application permission); the owner stays on the group.
  • GroupLogo fails — uploading the group photo (graphClient.Groups[id].Photo) requires Group.ReadWrite.All.
  • The group-level Office365GroupCfg.SensitivityLabel fails — assigning it writes to the group (graphClient.Groups[id]), which requires Group.ReadWrite.All. See Group-level sensitivity label.
  • Groups created by another app registration cannot be updated — switching to a different app registration makes existing groups unmanageable under this set.
  • Automatic cleanup of soft-deleted groups still requires Directory.ReadWrite.All (unchanged).
  • The Teams design works with this set when Team.Create is added (verified end-to-end): the service adds the configured owners before creating the team, which satisfies the owner requirement for app-only team creation. Custom team channels, tabs, and team settings were not exercised and may require additional Teams permissions.

Neither the full nor the reduced set includes InformationProtectionPolicy.Read.All, which the group-level sensitivity label also needs regardless of which set is used — see Group-level sensitivity label below.

# Teams

Used by: MatterOffice365Group only, when Office365GroupCfg.Team also resolves to true — Teams is a flag on the Office 365 Groups design, not a separate ClientMatterDesign value.

Same as Office 365 Groups, plus:

API Permission Why needed Broader alternative
Microsoft Graph Team.Create (opens new window) Creates the Microsoft Team on top of the Office 365 group (app-only team creation). Directory.ReadWrite.All — far broader than needed; not recommended unless already required for another reason.

Additional Team permissions might be needed depending on the Teams features used. SPTeamChannels (channels, tabs) is Graph-only, same as the group itself.

# Planner

Used by: MatterOffice365Group (via Office365GroupCfg.PlannerSet) — Planner boards need a Microsoft 365 group-backed site, which that design always provisions. PlannerSet can also be set on a MatterDocLib design's DocLibCfg (the only DocLibCfg-based design that wires it — ClientSiteCollection_MatterDocLib and ClientSite_MatterDocLib never construct SPPlanner), but it only works when that document library's site happens to already be group-backed; otherwise it fails to locate a Microsoft 365 group (DetermineHostingGroupForPlanner logs Could not create a planner ... because it is not part of a microsoft 365 group) and no board is created. The Planner Set Excel file handler (PlannerSetExcel) also uses this same permission set, resolving the target group by MatterCode independent of ClientMatterDesign — so these permissions are needed whenever that file handler is in use, even on designs whose provisioning path wouldn't otherwise need Planner.

Used when a Planner Configuration (PlannerCfg) is referenced from an Office365GroupCfg or a DocLibCfg (PlannerSet). Planner boards are Microsoft 365 Group based and are only supported on SharePoint Online, so this applies on top of whichever permission set above provisions the group-backed site (Office 365 Groups, Teams, or a document library hosted on a group-backed site). Planner board operations (SPPlanner's plan/bucket/task calls) are Graph-only; SPPlanner additionally uses SharePoint CSOM to read the PlannerUrlColumnName configuration and to record the resulting plan URL back on the matter list — both covered by the SharePoint permission already required for Document libraries.

API Permission Why needed Broader alternative
Microsoft Graph Tasks.ReadWrite.All (opens new window) Creates, updates, and deletes the Planner plan, buckets, categories, and tasks configured via PlannerCfg. Group.ReadWrite.All — Microsoft Graph accepts it as an alternative for Planner writes, since plans/tasks belong to the group. If the full Office 365 Groups permission set (Group.ReadWrite.All) is already granted, Tasks.ReadWrite.All is redundant. Under the reduced Group.Create set it is not covered and must be granted separately.
Microsoft Graph Group.Read.All (opens new window) Looks up the Microsoft 365 group's existing Planner plans before creating a new one. Group.ReadWrite.All (redundant if already granted).

Group.Read.All is already covered by the Office 365 Groups / Teams permission sets above; Tasks.ReadWrite.All is additional and not implied by the reduced Group.Create set (see alternative column).

# Sensitivity Labels

SensitivityLabelRepository always calls Microsoft Graph directly over HTTP (MSGraph.GetAppToken()) to resolve a label name to its id — every path below needs InformationProtectionPolicy.Read.All for that lookup alone. Three separate, independently-configured features build on it, each needing different permissions on top:

# Group-level sensitivity label

Used by: MatterOffice365Group only — SensitivityLabel is a property of Office365GroupCfg.

Set via Office365GroupCfg.SensitivityLabel. After resolving the label id, SPOffice365Group assigns it directly to the Microsoft 365 group (graphClient.Groups[id].Request().UpdateAsync(group) with assignedLabels).

API Permission Why needed Broader alternative
Microsoft Graph InformationProtectionPolicy.Read.All Resolves the configured label name to its id. None.
Microsoft Graph Group.ReadWrite.All Assigning a label writes to the group. Already required by the full Office 365 Groups permission set; not covered by the reduced Group.Create set. Directory.ReadWrite.All — not recommended unless already required elsewhere.

# Library default sensitivity label

Used by: every ClientMatterDesignDefaultSensitivityLabelName is a property of DocLibCfg, same as Document libraries above.

Set via DocLibCfg.DefaultSensitivityLabelName. After resolving the label id, SPDocumentLibrary sets it via CSOM (List.DefaultSensitivityLabelForLibrary) — no further Graph call.

API Permission Why needed Broader alternative
Microsoft Graph InformationProtectionPolicy.Read.All Resolves the configured label name to its id. None.
SharePoint (certificate authentication) Sites.Selected (or the broader permission already granted for Document libraries) Writing List.DefaultSensitivityLabelForLibrary is a plain CSOM list update. Sites.FullControl.All (tenant-wide).

# Per-file sensitivity label

Used by: every ClientMatterDesign — the file handler resolves the target document library by MatterCode or Url, independent of which design provisioned it.

Applied by the Update Doclib File Sensitivity Label file handler, via SPDocument.UpdateFileSensitivityLabelSensitivityLabelRepository.GetForFile/SetForFile. Unlike the two features above, this calls the Graph file sensitivity-label endpoints directly (extractSensitivityLabels/assignSensitivityLabel) — the code's own log messages, emitted on a failed call, name the exact permissions:

API Permission Why needed Broader alternative
Microsoft Graph InformationProtectionPolicy.Read.All Resolves the configured label name to its id. None.
Microsoft Graph Sites.Read.All, Files.Read.All Reading the file's current sensitivity label before deciding whether to overwrite it. Sites.ReadWrite.All, Files.ReadWrite.All (covers the write path below too).
Microsoft Graph Sites.ReadWrite.All, Files.ReadWrite.All Setting the sensitivity label on the file. None — these are already the write-level permissions for this operation.

None of the three paths above are covered by Sites.FullControl.All (SharePoint) or any other permission listed elsewhere in this document — each must be granted independently, on top of whichever site/group permission set is in use.

# TermStore narrower alternative

TermStore.ReadWrite.All is listed everywhere above because SPTermStore.CreateValueAsString calls CreateTerm on demand for any term label that isn't already found in the target term set. This is controlled by the CreateTermIfNotFound setting, which defaults to true.

If CreateTermIfNotFound is disabled, or the term store is fully pre-populated so provisioning never encounters a missing term, no CreateTerm call is ever made and TermStore.Read.All is sufficient everywhere TermStore.ReadWrite.All is listed in this document. This is a narrower permission, not a broader one — grant it only when confident no new terms will ever need to be created during provisioning, since a term that turns out to be missing then fails instead of being auto-created.

TermStore.* is a SharePoint CSOM Taxonomy operation throughout this codebase (Microsoft.SharePoint.Client.Taxonomy) — there is no Microsoft Graph equivalent in use, even though Microsoft Graph also offers its own, unrelated TermStore.Read.All / TermStore.ReadWrite.All permissions for its newer term store API.

# Granting permissions in Azure

In the app registration's API permissions page:

  1. Click + Add a permission.
  2. Click Microsoft Graph.
  3. Click Application permissions.
  4. Search for the required permission, select its checkbox, then click Add permissions. Repeat for each permission needed.
  5. Click Grant admin consent for <tenant> after adding the permissions.
Last Updated: 8/27/2026, 4:27:20 PM